
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <iostream>
#include <fstream>
#include <string>

#include "egg.h"

Egg::Egg()
{
	numVertices = 0;
	numTriangles = 0;

	vertices = new float[6400*3];
	normals = new float[6400*3];
	texCoords = new float[6400*3];
	indices = new int[6400*3];  //vert, norm, tex, ind
	alloc = new int[4]; alloc[0] = alloc[1] = alloc[2] = alloc[3] = 6400*3;
	animationAngle = 0;
}

Egg::Egg(std::string filename)
{
	numVertices = 0;
	numTriangles = 0;

	vertices = new float[6400*3];
	normals = new float[6400*3];
	texCoords = new float[6400*3];
	indices = new int[6400*3];  //vert, norm, tex, ind
	alloc = new int[4]; alloc[0] = alloc[1] = alloc[2] = alloc[3] = 6400*3;
	animationAngle = 0;
	
	loadEgg(filename);
}


void Egg::loadEgg( std::string filename )
{
	filename.append(".egg");
	fopen_s(&egg, filename.c_str(), "r");

	if(egg==NULL){
		printf("Cannot load egg file\n");
		return;
	}

	startingAlloc = 64*3;
	alloc = new int[4];
	alloc[0] = alloc[1] = alloc[2] = alloc[3] = 64*3;
	
	char *str = new char[256];

	while(fgets(str, 256, egg))
	{
		if(strstr(str, "<Vertex>") != NULL)				//For each <Vertex>
			parseVertexBlock(str);
		else if(strstr(str, "<Polygon>") != NULL)
			parsePolygonBlock(str);
		//checkAllocation(vertices, int alloc, int num)
	}
}

void Egg::parseVertexBlock(char *str)
{
	parseVertex(str);
	parseNormal(str);
	parseTexCoord(str);

	numVertices++;
}

void Egg::parsePolygonBlock(char *str)
{
	int i=0;
	fgets(str, 256, egg);						//now on RGBA
	fgets(str, 256, egg);						//now on TRef
	fgets(str, 256, egg);						//now on VertexRef
	i = 0;
	for(int num=0; num<3; num++){					//Get 3 indices
		while(!(str[i]>='0' && str[i]<='9')) i++;	//	skip ahead to numbers
		char *val = new char[8];
		int n=0;
		while(str[i]>='0' && str[i]<= '9')
			val[n++] = str[i++];					//	Grab the number!
		indices[(numTriangles*3)+num] = (int)atof(val)-1;
	}
	numTriangles++;
}

void Egg::parseVertex(char *str)
{
	fgets(str, 256, egg);						//next line
												//get 3 floats for vertex
	int i=0;
	for(int num=0; num<3; num++){					//get individual numbers in vertex
		while(str[i]==' ') i++;						//skip spaces
		char *val = new char[16];
		int n = 0;
		while(str[i] && str[i]!=' ' && str[i]!='\n')//For all not-whitespace
			val[n++] = str[i++];					//	Grab the number!
		vertices[(numVertices*3)+num] = (float)atof(val);	//Add to vertices array
	}
}
void Egg::parseNormal(char *str)
{
	fgets(str, 256, egg);						//next line
												//get 3 floats for normal
	int i=0;
	for(int num=0; num<3; num++){					//get individual numbers in normal
		while(!((str[i]>='0' && str[i]<='9') ||
				str[i] == '-'))						//skip to numeral or -
			i++;
		char *val = new char[16];
		int n = 0;
		while(str[i]!=' ' && str[i]!='\n')			//For all not-whitespace
			val[n++] = str[i++];					//	Grab the number!
		normals[(numVertices*3)+num] = (float)atof(val);	//add to normal array
	}
}
void Egg::parseTexCoord(char *str)
{
	fgets(str, 256, egg);						//next line
												//get 2 floats for texCoord
	int i=0;
	for(int num=0; num<2; num++){					//get individual numbers in texCoord
		while(!(str[i]>='0' && str[i]<='9')) i++;		//skip to numeral
		char *val = new char[16];
		int n = 0;
		while(str[i]!=' ' && str[i]!='\n')			//For all not-whitespace
			val[n++] = str[i++];					//	Grab the number!
		texCoords[(numVertices*2)+num] = (float)atof(val);	//add to normal array
	}
}

void Egg::doubleArrayAllocation(float*& ar, int size)
{
	int newSize = size*2;
	float* newAr = new float[newSize];
	for(int i=0; i<size; i++)
		newAr[i] = (float)ar[i];
	delete [] ar;
}

void Egg::checkAllocation(float*& ar, int alloc, int num)
{
	if( num+1 == alloc )
		doubleArrayAllocation(ar, alloc);
}

void Egg::draw()
{
	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
	glEnableClientState( GL_VERTEX_ARRAY );
	glTexCoordPointer( 2, GL_FLOAT, 0, texCoords );
	glVertexPointer( 3, GL_FLOAT, 0, vertices );
	glDrawElements( GL_TRIANGLES, numTriangles*3, GL_UNSIGNED_INT, indices );
	glDisableClientState( GL_TEXTURE_COORD_ARRAY );
	glDisableClientState( GL_VERTEX_ARRAY );
}
